<!DOCTYPE html>
<html lang="en-us">
<head><head>
    <meta name="google-site-verification" content="9vIieCe-Qpd78QOmBl63rGtIVbhY6sYyuxX3j8XWBA4" />
    <meta name="baidu-site-verification" content="LRrmH41lz7" />
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <meta name="baidu-site-verification" content="HGLXRsUXC4" />

    
    <meta name="baidu-site-verification" content="code-ANZvlnN0Xr" />

    
    <meta name="description" content="随着 TIOBE 10月份的编程语言排行的发布，C&#43;&#43;重回第三的位置，新兴的 Swift 和 Go 表现出强劲的上升趋势。与此同时，虽然目前 Java 的领头位置尚未出现有力挑战，我们希望能够在基础设施的建设上预留跨语言的可扩展设计。同时，跨语言的挑战也是工程实际面临的现状，蚂蚁内部如 AI、IoT，算法等缺少 JVM 原生支持的领域，往往不可避免地需要涉及到跨语言调用的问题。">
    
    <meta name="keyword"  content="liangyuanpeng|LanLiang|OpenYurt|Knative|Pulsar|Prometheus|Halo||边缘计算kubernetes|Docker|CloudNative|Golang|Rust|Istio|微服务">
    <link rel="shortcut icon" href="img/logo.png">


    
    <meta property="og:image" content="https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg" />
    <meta name="twitter:image" content="https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg" />


    <title>转|SOFARPC跨语言支持剖析-liangyuanpeng的博客 | liangyuanpeng&#39;s Blog</title>

    <link rel="canonical" href="/post/sofarpc-mult-language/">

    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/iDisqus.min.css"/>

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369744/hugo/css/bootstrap.min.css">

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/hux-blog.min.css">

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/syntax.css">

    
    <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    
    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369966/hugo/js/jquery.min.js"></script>

    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369966/hugo/js/bootstrap.min.js"></script>

    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369964/hugo/js/hux-blog.min.js"></script>

    
    <script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "f73bc0092aeb491d89984c0eb5a87ac2"}'></script>
</head>

</head>

<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Hi,I`m lan</a>
        </div>

        
        
        <div id="huxblog_navbar">
            <div class="navbar-collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li>
                        <a href="/">Home</a>
                    </li>
                    
                    <li>
                        <a href="categories/cloudnative">cloudnative</a>
                    </li>
                    
                    <li>
                        <a href="categories/devops">devops</a>
                    </li>
                    
                    <li>
                        <a href="categories/iot">iot</a>
                    </li>
                    
                    <li>
                        <a href="categories/kubernetes">kubernetes</a>
                    </li>
                    
                    <li>
                        <a href="categories/tech">tech</a>
                    </li>
                    

                    
		            <li>
                        <a href="search">SEARCH <img src="img/search.png" height="15" style="cursor: pointer;"></a>
		            </li>
                    
                </ul>
            </div>
        </div>
        
    </div>
    
</nav>
<script>
    
    
    
    var $body   = document.body;
    var $toggle = document.querySelector('.navbar-toggle');
    var $navbar = document.querySelector('#huxblog_navbar');
    var $collapse = document.querySelector('.navbar-collapse');

    $toggle.addEventListener('click', handleMagic)
    function handleMagic(e){
        if ($navbar.className.indexOf('in') > 0) {
        
            $navbar.className = " ";
            
            setTimeout(function(){
                
                if($navbar.className.indexOf('in') < 0) {
                    $collapse.style.height = "0px"
                }
            },400)
        }else{
        
            $collapse.style.height = "auto"
            $navbar.className += " in";
        }
    }
</script>




<style type="text/css">
    header.intro-header{
        background-image: url('https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg')
    }
</style>
<header class="intro-header" >
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <div class="tags">
                       
                       <a class="tag" href="/tags/rpc" title="rpc">
                           rpc
                        </a>
                        
                       <a class="tag" href="/tags/sofa" title="sofa">
                           sofa
                        </a>
                        
                       <a class="tag" href="/tags/sofastack" title="sofastack">
                           sofastack
                        </a>
                        
                       <a class="tag" href="/tags/middleware" title="Middleware">
                           Middleware
                        </a>
                        
                    </div>
                    <h1>转|SOFARPC跨语言支持剖析</h1>
                    <h2 class="subheading"></h2>
                    <span  class="meta">Posted by 梁远鹏 on 2018-12-11
                        
                        <span id="busuanzi_container_page_pv">|<span id="busuanzi_value_page_pv"></span><span>
                            <span id="/post/sofarpc-mult-language/" class="leancloud_visitors meta_data_item" data-flag-title="">
    <span class="post-meta-item-icon">
      <span class="octicon octicon-eye"></span> 
    </span>
    <i class="fa fa-eye"></i>
    <span class="old-visitors-count" style="display: none;"></span>
    <span class="leancloud-visitors-count"></span>
</span>






                            阅读 </span></span>|<span class="post-date">共3704字</span>，阅读约<span class="more-meta"> 8 分钟</span>
                        
                    </span>
                </div>
            </div>
        </div>
    </div>
</header>




<article>
    <div class="container">
        <div class="row">

            
            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                post-container">

		
                <header>
                <h2>TOC</h2>
                </header>
                <nav id="TableOfContents">
  <ul>
    <li><a href="#前言">前言</a></li>
    <li><a href="#总体设计">总体设计</a></li>
    <li><a href="#通讯协议和序列化协议">通讯协议和序列化协议</a>
      <ul>
        <li><a href="#json-over-http">JSON Over HTTP</a></li>
        <li><a href="#hessian-over-bolt">Hessian Over BOLT</a></li>
        <li><a href="#protobuf-over-bolt">Protobuf Over BOLT</a></li>
        <li><a href="#others-over-bolt">Others Over BOLT</a></li>
      </ul>
    </li>
    <li><a href="#服务发现">服务发现</a>
      <ul>
        <li><a href="#各语言对接注册中心">各语言对接注册中心</a></li>
        <li><a href="#各语言对接sofamosn">各语言对接SOFAMosn</a></li>
      </ul>
    </li>
    <li><a href="#参考资料">参考资料</a></li>
    <li><a href="#结语">结语</a></li>
  </ul>
</nav>
		
		<h2 id="前言">前言</h2>
<p>随着 TIOBE 10月份的编程语言<a href="https://www.tiobe.com/tiobe-index/">排行</a> 的发布，C++重回第三的位置，新兴的 Swift 和 Go 表现出强劲的上升趋势。<br>
与此同时，虽然目前 Java 的领头位置尚未出现有力挑战，我们希望能够在基础设施的建设上预留跨语言的可扩展设计。同时，跨语言的挑战也是工程实际面临的现状，蚂蚁内部如 AI、IoT，算法等缺少 JVM 原生支持的领域，往往不可避免地需要涉及到跨语言调用的问题。</p>
<p>本文将为大家介绍 基于 SOFARPC 的微服务应用在面临跨语言调用时的方案和实现。</p>
<h2 id="总体设计">总体设计</h2>
<p>经过前面几篇对 SOFARPC 的 BOLT 协议和序列化这些的介绍，相信大家已经对 RPC 有了一些自己的理解，提到跨语言，我们会首先想到其他语言调用 Java，Java 调用其他语言，那么这里的跨，体现在代码上，到底跨在哪里？</p>
<p>从跨语言的实现上来说，主要解决两个方面的问题：</p>
<ul>
<li>跨语言的通讯协议和序列化协议</li>
<li>跨语言服务发现</li>
</ul>
<p>另外从跨语言的落地来说，还得解决一个平滑兼容的问题。</p>
<p>业界常见的做法是一般是通过 DNS 和 HTTP 来解决跨语言的问题，但是在内部已经有完善技术栈体系的情况下，直接切换一个新的方案显然是不合适的，所以蚂蚁内部是在已有的技术体系基础上进行改进。</p>
<p>蚂蚁内部使用的通讯协议是Bolt，序列化协议是Hessian。我们知道，服务端和客户端在请求和返回之间携带的结构化的业务数据，需要在传输到达对端后，被本地的语言能够易于解析消费。<br>
由于语言本身特性的差异，同一对象的在序列化和反序列化的转换后，结构可能有差异，但是需要保证其转换操作是可逆的。以上这点Hessian做的不是很好，其跨语言的兼容性不能满足跨语言的需求，所以另外一个可行的方案就是就是选择其它基于 IDL 的序列化协议，例如<code>Protobuf</code>。</p>
<p>现成的服务注册中心一般都有一些多语言解决方案，像<code>Zookeeper</code>、<code>SOFARegistry</code>、<code>Consul</code>、<code>etcd</code>等都有多语言客户端，所以服务发现这块问题不算太大。</p>
<p>例如下面就是一个基于注册中心 + Bolt协议 + Protobuf序列化的设计图。</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544533804/hugo/blog.github.io/sofa-rpc/kyyzc/1540814354303-c1d8fde9-4de6-44d7-bd3e-67f7f6fd0fe6.png" alt="跨语言.png | center | 747x440" title=""></p>
<h2 id="通讯协议和序列化协议">通讯协议和序列化协议</h2>
<p>通讯协议只要跨语言各方约定清楚，大家安装约定实现即可，而序列化协议则需要较多的考量。
序列化的协议选择列出一些考虑要点：</p>
<ul>
<li>是否采用具备自我描述能力的序列化方案，如不需要借助一些 schema 或者接口描述文件。</li>
<li>是否为语言无关的，包括脚本语言在内。</li>
<li>是否压缩比例足够小，满足网络传输场景的要求。</li>
<li>是否序列化和反序列化的性能均足够优秀。</li>
<li>是否向前/向后兼容，能够处理传输对象的新增属性在服务端和客户端版本不一致的情况。</li>
<li>是否支持加密、签名、压缩以及扩展的上下文。</li>
</ul>
<h3 id="json-over-http">JSON Over HTTP</h3>
<p>首先，说到跨语言，序列化支持，肯定有同学会问，为什么不直接通过 Http的Json来搞定呢？
虽然得益于JSON和HTTP在各个语言的广泛支持，在多语言场景下改造支持非常便捷，能够低成本的解决网络通讯和序列化的问题。服务发现的过程则可以使用最简单的固定URL（协议+域名+端口+路径）的形式，负载均衡依赖于F5或者LVS等实现。
但是这个方案的有明显的局限性：</p>
<ol>
<li>HTTP 作为无状态的应用层协议，在性能上相比基于传输层协议（TCP）的方案处于劣势。HTTP/1.1后可以通过设置keep-alive使用长连接，可以一定程度上规避建立连接的时间损耗；然而最大的问题是，客户端线程采用了 request-response 的模式，在发送了 request 之后被阻塞，直到拿到 response 之后才能继续发送。这一问题直到 HTTP/2.0 才被解决。</li>
<li>JSON 是基于明文的序列化，较二进制的序列化方案，其序列化的结果可读性强，但是压缩率和性能仍有差距，这种对于互联网高并发业务场景下，意味着硬件成本的提升。</li>
<li>对于网络变化的响应。订阅端处理不够强大。</li>
</ol>
<h3 id="hessian-over-bolt">Hessian Over BOLT</h3>
<p>在否决了上一个方案后，我们继续看，蚂蚁内部，最开始的时候，SOFARPC 还没有支持 Protobuf 作为序列化方式，当时为了跨语言，NodeJs的同学已经在此基础上，用 js 重写了一个 hessian 的版本，完成了序列化。也已经在线上平稳运行。但是当我们要扩展给其他语言的时候，重写 hessian 的成本太高。而且 Java语言提供的接口和参数信息，其他语言也需要自己理解一遍，对应地转换成自己的语言对象。因此该方案在特定场景下是可行的。但不具备推广至其他语言的优势。</p>
<p>Node的实现版本可以参考：<a href="https://github.com/alipay/sofa-rpc-node">https://github.com/alipay/sofa-rpc-node</a></p>
<h3 id="protobuf-over-bolt">Protobuf Over BOLT</h3>
<p>Protobuf 基于IDL，本身具备平台无关、跨语言的特性，是一个理想的序列化方案。但是需要先编写proto文件，结构化地描述传输的业务对象，并生成中间代码。</p>
<p>由于要重点介绍一下这种方案，因此再次回顾一下SOFABolt的协议规范部分，便于后面的解释。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-plain" data-lang="plain">Request command protocol for v1
0     1     2           4           6           8          10           12          14         16
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|proto| type| cmdcode   |ver2 |   requestId           |codec|        timeout        |  classLen |
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|headerLen  | contentLen            |                             ... ...                       |
+-----------+-----------+-----------+                                                           +
|               className + header  + content  bytes                                            |
+                                                                                               +
|                               ... ...                                                         |
+-----------------------------------------------------------------------------------------------+

codec: code for codec 序列化,hessian 是1,pb 是11,java 是2

Response command protocol for v1
0     1     2     3     4           6           8          10           12          14         16
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|proto| type| cmdcode   |ver2 |   requestId           |codec|respstatus |  classLen |headerLen  |
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| contentLen            |                  ... ...                                              |
+-----------------------+                                                                       +
|                         className + header  + content  bytes                                  |
+                                                                                               +
|                               ... ...                                                         |
+-----------------------------------------------------------------------------------------------+
respstatus: response status 服务端响应结果状态
</code></pre></div><p>对于现有的通信协议，我们改进时，将 content部分存储为入参对象和返回值，他们都是 pb序列化之后的值。这样将直接对接到现在的协议上。又利用了 BOLT的通信协议。</p>
<p>以下描述了跨语言中对 Protobuf协议的使用：</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544533826/hugo/blog.github.io/sofa-rpc/kyyzc/1540814966719-289d3d32-3642-4178-a7f3-cce928ae6a5e.png" alt="pb 序列化.png | center | 747x433" title=""></p>
<p>首先我们看 header 部分，是简单的扁平化的 KV。默认会增加以下三个 Entry：</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>sofa_head_method_name</td>
<td>对方方法名</td>
<td>对应 SofaRequest#methodName</td>
</tr>
<tr>
<td>sofa_head_target_app</td>
<td>对方的应用名</td>
<td>对应 SofaRequest#targetAppName</td>
</tr>
<tr>
<td>sofa_head_target_service</td>
<td>对方的服务唯一命名</td>
<td>对应 SofaRequest#targetServiceUniqueName</td>
</tr>
<tr>
<td>sofa_head_response_error</td>
<td>true/false</td>
<td>仅在响应中出现</td>
</tr>
</tbody>
</table>
<p>我们再看 body 部分，根据 Protobuf 的实现，所有被序列化的对象均实现了 MessageLite 接口，然而由于多个Classloader 存在的可能，代码上为了避免强转 MessageList 接口的失败，并未直接调用 toByteArray 方法，而是通过反射机制调用 toByteArray 获得 byte 数组。</p>
<p>针对SofaRequest这个 RPC中的传输对象，由于 Protobuf 仅支持对于单个对象的序列化，因此 SofaRequest 类型的对象进行序列化，实际支持的是 SofaRequest#methodArgs 数组中的首个元素对象进行的序列化，也就是说目前我们仅支持一个入参对象。</p>
<p>针对 SofaResponse 这个响应对象，当出现框架异常或者返回对象是一个 Throwable 代表的业务异常时，直接将错误消息字符串序列化；并在响应头中设置 sofa_head_response_error=true，其他情况才序列化业务返回对象。这样可以避免比如 Java 语言的错误栈，由于含有 一些线程类和异常类，其他语言是无法解析的。</p>
<p>反序列化的过程稍复杂一些，上游调用传入SofaRequest/SofaResponse的实例，先要在空白的SofaRequest对象中填入前文中在 header 反序列化中的解析的头部信息，接着根据Header中接口+方法名找到等待反序列化对象的 class，并借助反射调用 parseFrom 接口生成对象，成为 SofaRequest#MethodArgs 的首个元素对象。</p>
<h3 id="others-over-bolt">Others Over BOLT</h3>
<p>在上一个方案的基础上，我们也可以支持更多的语言，对JSON、Kyro的支持也分别处于开发和规划中。 JSON的支持已经开发完成待合并。这里不再做过多说明。</p>
<h2 id="服务发现">服务发现</h2>
<p>跨语言各方约定了通讯协议和序列化协议后，就可以完成各自的服务端和客户端实现，跨语言已经能完成点对点的调用了。但在实际的线上场景下，我们还是需要通过注册中心等服务发现的形式，来保证跨语言调用的可用性。目前，有两种可选的方案。</p>
<h3 id="各语言对接注册中心">各语言对接注册中心</h3>
<p>对于服务发现，前面说到的最早进行跨语言的 NodeJs 实现了对接 SOFA Registry 的能力。<br>
直接通过对 Java原生序列化和一些 hessian 的重写，来操作完成了。在蚂蚁内部，这种方案在只有 Node的情况下是可以的，但是更通用的场景下。<br>
如果我们有了新的注册中心，要对接更多的注册中心，其他语言在语言表达上的差异性，使得这种方案很难推广到其他项目。NodeJs 版本的 hessian：<a href="https://github.com/alipay/sofa-hessian-node">https://github.com/alipay/sofa-hessian-node</a></p>
<h3 id="各语言对接sofamosn">各语言对接SOFAMosn</h3>
<p>由于每个语言都去对接对接中心存在一定的难度，也不具备可推广性，而在蚂蚁内部，我们已经在一些跨语言的场景下，运行 SOFAMosn，通过 SOFAMosn，我们对接了站内的注册中心，其他的语言，仅需要将自己需要订阅和发布的信息，通过 Http的接口形式，通知 SOFAMosn，SOFAMosn 将会将这些信息和注册中心进行注册和订阅，并维持地址信息。</p>
<p>这样对于其他语言来说，仅需要非常简单的 json请求，就完成了跨语言的服务注册和订阅。后续新注册中心的对接等等。其他语言都不再需要理解。相关的 sdk。我们已经开发并实现完成。对于 SOFAMosn 的更多介绍，可以参看 SOFAMosn官网：<a href="http://www.sofastack.tech/sofa-mosn/docs/README">http://www.sofastack.tech/sofa-mosn/docs/README</a></p>
<table>
<thead>
<tr>
<th>语言</th>
<th>实现</th>
</tr>
</thead>
<tbody>
<tr>
<td>python</td>
<td><a href="https://github.com/alipay/sofa-bolt-python">https://github.com/alipay/sofa-bolt-python</a></td>
</tr>
<tr>
<td>node</td>
<td><a href="https://github.com/alipay/sofa-rpc-node">https://github.com/alipay/sofa-rpc-node</a></td>
</tr>
<tr>
<td>c++</td>
<td><a href="https://github.com/alipay/sofa-bolt-cpp">https://github.com/alipay/sofa-bolt-cpp</a></td>
</tr>
</tbody>
</table>
<p>当然如果你并不需要进行服务寻址，或者能够接受硬负载或者固定 IP的调用方式。也可以直接使用。</p>
<h2 id="参考资料">参考资料</h2>
<p>SOFA 微服务多语言演进 <a href="https://mp.weixin.qq.com/s/kfbDIq4GgdSU7KC2jqSRAw">https://mp.weixin.qq.com/s/kfbDIq4GgdSU7KC2jqSRAw</a><br>
SOFARPC 框架之总体设计与扩展机制 <a href="https://mp.weixin.qq.com/s/ZKUmmFT0NWEAvba2MJiJfA">https://mp.weixin.qq.com/s/ZKUmmFT0NWEAvba2MJiJfA</a><br>
蚂蚁通信框架实践 <a href="https://mp.weixin.qq.com/s/JRsbK1Un2av9GKmJ8DK7IQ">https://mp.weixin.qq.com/s/JRsbK1Un2av9GKmJ8DK7IQ</a><br>
JVM Serializers <a href="https://github.com/eishay/jvm-serializers/wiki">https://github.com/eishay/jvm-serializers/wiki</a></p>
<h2 id="结语">结语</h2>
<p>至此，我们介绍了 SOFARPC 中对于 Protobuf 的跨语言实现，并介绍了一些 NodeJs 对跨语言的支持，最后介绍了我们用 SOFAMosn 实现通用的服务发现。</p>
<p>在大多数场景下，我们更推荐是使用 SOFAMosn来做服务寻址，这样之后 Mosn 层面的一些限流熔断。也可以在多语言上进行使用。</p>
<p>而对一些场景比较简单，能够容忍固定 IP调用，或者使用硬件负载均衡设备的。也可以直接使用各个跨语言客户端，进行直接开发调用。</p>
<hr>
<p>文章转自<a href="http://www.sofastack.tech/post/nuo9ph">剖析 | SOFARPC 框架】之SOFARPC 跨语言支持剖析</a></p>


        <h2>微信公众号</h2>
<p>扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github，看看我都在了解什么技术，在页面底部可以找到我的Github。</p>
<img src="https://res.cloudinary.com/lyp/image/upload/v1581729955/hugo/blog.github.io/qrcode_for_sikekafeidou.jpg" alt="wechat-account-qrcode">


                <hr>

                <ul class="pager">
                    
                    <li class="previous">
                        <a href="/post/sofarpc-route-impl/" data-toggle="tooltip" data-placement="top" title="转|SOFARPC路由实现剖析">&larr; 转|SOFARPC路由实现剖析</a>
                    </li>
                    
                    
                    <li class="next">
                        <a href="/post/sofarpc-annotation/" data-toggle="tooltip" data-placement="top" title="转|SOFARPC注解支持剖析">转|SOFARPC注解支持剖析 &rarr;</a>
                    </li>
                    
                </ul>

            
<script src="https://utteranc.es/client.js"
repo="liangyuanpeng/liangyuanpeng.github.io"
issue-term="title"
theme="github-light"
crossorigin="anonymous"
async>
</script>



            </div>

            


            
            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                sidebar-container">

                
                <section>
                    <hr class="hidden-sm hidden-xs">
                    <h5><a href="/tags/">FEATURED TAGS</a></h5>
                    <div class="tags">
                     
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/blog" title="blog">
                                blog
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/chirpstack" title="chirpstack">
                                chirpstack
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/ci/cd" title="ci/cd">
                                ci/cd
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/cloudnative" title="cloudnative">
                                cloudnative
                            </a>
                        
                    
                        
                            <a href="/tags/cncf" title="cncf">
                                cncf
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/docker" title="docker">
                                docker
                            </a>
                        
                    
                        
                            <a href="/tags/docker-compose" title="docker-compose">
                                docker-compose
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/fluentd" title="fluentd">
                                fluentd
                            </a>
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/halo" title="halo">
                                halo
                            </a>
                        
                    
                        
                            <a href="/tags/hugo" title="hugo">
                                hugo
                            </a>
                        
                    
                        
                            <a href="/tags/image" title="image">
                                image
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/iot" title="iot">
                                iot
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/kubernetes" title="kubernetes">
                                kubernetes
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/lorawan" title="lorawan">
                                lorawan
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/middleware" title="middleware">
                                middleware
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/mq" title="mq">
                                mq
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/ops" title="ops">
                                ops
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/prometheus" title="prometheus">
                                prometheus
                            </a>
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/rpc" title="rpc">
                                rpc
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/sofa" title="sofa">
                                sofa
                            </a>
                        
                    
                        
                            <a href="/tags/sofastack" title="sofastack">
                                sofastack
                            </a>
                        
                    
                        
                            <a href="/tags/springboot" title="springboot">
                                springboot
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                    </div>
                </section>



               

                
                
            </div>

            
            
            <div class="
            col-lg- col-lg-offset-2
            col-md-10 col-md-offset-1
            ">
            <section>
                <hr class="hidden-sm hidden-xs">
                

<h2>相关文章</h2>
<ul style="margin-bottom: 25px;">
    
    <li><a href="/post/sofarpc-serializer/">转|SOFARPC序列化比较</a></li>
    
    <li><a href="/post/sofarpc-annotation/">转|SOFARPC注解支持剖析</a></li>
    
    <li><a href="/post/sofarpc-route-impl/">转|SOFARPC路由实现剖析</a></li>
    
    <li><a href="/post/sofarpc-heartbeat-connect/">转|SOFARPC连接管理与心跳剖析</a></li>
    
    <li><a href="/post/sofarpc-sync-async/">转|SOFARPC同步异步实现剖析</a></li>
    
    <li><a href="/post/sofarpc-modle/">转|SOFARPC线程模型剖析</a></li>
    
    <li><a href="/post/sofarpc-trace/">转|SOFARPC链路追踪剖析</a></li>
    
    <li><a href="/post/sofarpc-design/">转|SOFARPC框架之总体设计与扩展机制</a></li>
    
    <li><a href="/post/%E5%8E%BB%E5%93%AA%E5%84%BF%E7%BD%91%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0/">去哪儿网消息队列设计与实现</a></li>
    
    <li><a href="/post/awesome-messagequeue/">AWESOME消息队列</a></li>
    
</ul>

            </section>
            </div>
            


        </div>
    </div>
</article>






<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <ul class="list-inline text-center">
                   
                    
                    <li>
                        <a target="_blank" href="https://github.com/liangyuanpeng">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                   
                    
                    <li>
                        <a href="mailto:liangyuanpengem@163.com">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-envelope fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
		    

                    
                    <li>
                        <a href="https://twitter.com/lan31793328">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                    
                    
                    <li>
                        <a target="_blank" href="https://www.zhihu.com/people/liangyuanpeng">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa  fa-stack-1x fa-inverse">知</i>
                            </span>
                        </a>
                    </li>
		    
                    
                    <li>
                        <a target="_blank" href="https://weibo.com/u/1908782280">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-weibo fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
		    

                    

		    
                    
                    
                </ul>
		<p class="copyright text-muted">
                    Copyright &copy; Hi,I`m lan , 2018
                    <br>
                    <a href="https://themes.gohugo.io/hugo-theme-cleanwhite">CleanWhite Hugo Theme</a> by <a href="https://zhaohuabing.com">Huabing</a> |
                    <iframe
                        style="margin-left: 2px; margin-bottom:-5px;"
                        frameborder="0" scrolling="0" width="100px" height="20px"
                        src="https://ghbtns.com/github-btn.html?user=zhaohuabing&repo=hugo-theme-cleanwhite&type=star&count=true" >
                    </iframe>
                </p>
            </div>
        </div>
    </div>
</footer>




<script>
    function async(u, c) {
      var d = document, t = 'script',
          o = d.createElement(t),
          s = d.getElementsByTagName(t)[0];
      o.src = u;
      if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
      s.parentNode.insertBefore(o, s);
    }
</script>






<script>
    
    if($('#tag_cloud').length !== 0){
        async("/js/jquery.tagcloud.js",function(){
            $.fn.tagcloud.defaults = {
                
                color: {start: '#bbbbee', end: '#0085a1'},
            };
            $('#tag_cloud a').tagcloud();
        })
    }
</script>


<script>
    async("https://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.js", function(){
        var $nav = document.querySelector("nav");
        if($nav) FastClick.attach($nav);
    })
</script>







<script>
    
    var _baId = 'fad9c137f8ce239f9b323d36c871f8e6';

    
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?" + _baId;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
</script>







</body>
</html>
